package web.protocols.action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ModelDriven;
import domain.entities.*;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import services.*;
import services.exceptions.NoProtocoloCompromisopaisSelectedException;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Namespace("/Protocols")
public class ProtocolsController extends MenuController implements ModelDriven{

    private Protocolo protocol;
    private String editableProtocoloId;
    private ProtocolCRUDService protocolCRUDService;
    private CompromisoPaisService compromisoPaisService;
    private ProtocoloCompromisopaisService protocoloCompromisopaisService;
    private DrogaService drogaService;
    private SpecialityCRUDService specialityCRUDService;
    private List<Compromisopais> countries;
    private LinkedHashMap<TherapeuticArea, ArrayList<Specialty>> languageMap;
    private LinkedHashMap<Protocolo, ArrayList<Compromisopais>> protocolosPaises;
    private TherapeuticAreaCRUDService therapeuticAreaCRUDService;
    private List<TherapeuticArea> therapeuticAreas = new ArrayList<TherapeuticArea>();
    private List<Droga> drogas;
    private List<Integer> chosenCountries;
    private List<Protocolo> list;

    private String drugName;

    private String llamada;

    private List<Specialty> specialtyList = new ArrayList<Specialty>();

    @Autowired
    public ProtocolsController(ProtocolCRUDService protocolCRUDService, CompromisoPaisService compromisoPaisService,
                               ProtocoloCompromisopaisService protocoloCompromisopaisService, DrogaService drogaService,
                               TherapeuticAreaCRUDService therapeuticAreaCRUDService, SpecialityCRUDService specialityCRUDService) {
        super(protocoloCompromisopaisService);
        this.protocolCRUDService = protocolCRUDService;
        this.compromisoPaisService = compromisoPaisService;
        this.protocoloCompromisopaisService = protocoloCompromisopaisService;
        this.drogaService = drogaService;
        this.therapeuticAreaCRUDService = therapeuticAreaCRUDService;
        this.specialityCRUDService = specialityCRUDService;

    }

    @Action(value="main", results={
            @Result(name="success",location="/protocols.tiles", type="tiles")
    })
    public String execute() {
        therapeuticAreas = therapeuticAreaCRUDService.list();
        specialtyList = specialityCRUDService.list();
        countries = compromisoPaisService.findAll();
        list = new ArrayList<Protocolo>(0);
        return SUCCESS;
    }

    @Action(value="list", results={
            @Result(name="success",location="/protocols.tiles", type="tiles")
    })
    public String list() {
        CriteriaProtocol cp = new CriteriaProtocol(protocol);
        list = protocolCRUDService.list(cp);
        protocolosPaises = new LinkedHashMap<Protocolo, ArrayList<Compromisopais>>(0);
        for(Protocolo p : list){
            ArrayList<Compromisopais> paises = new ArrayList<Compromisopais>(0);
            for(ProtocoloCompromisopais pcp : p.getProtocoloCompromisopaises()){
                paises.add(pcp.getCompromisopais());
            }
            protocolosPaises.put(p, paises);
        }
        therapeuticAreas = therapeuticAreaCRUDService.list();
        specialtyList = specialityCRUDService.list();

        return SUCCESS;
    }

    @Action(value="create", results={
            @Result(name="success",location="/protocols.create.tiles", type="tiles"),
    })
    public String create() {
        drogas = drogaService.getDrogas();
        therapeuticAreas = therapeuticAreaCRUDService.list();
        languageMap = new LinkedHashMap();

        for(TherapeuticArea t : therapeuticAreas){
            languageMap.put(t, new ArrayList<Specialty>(t.getSpecialities()));
        }

        countries = compromisoPaisService.findAll();
        return SUCCESS;
    }

    @Action(value="edit", results={
            @Result(name="success",location="/protocols.create.tiles", type="tiles"),
            @Result(name="edit",location="/protocols.edit.tiles", type="tiles"),
    })
    public String edit() throws NoProtocoloCompromisopaisSelectedException {
        drogas = drogaService.getDrogas();
        therapeuticAreas = therapeuticAreaCRUDService.list();
        languageMap = new LinkedHashMap();

        for(TherapeuticArea t : therapeuticAreas){
            languageMap.put(t, new ArrayList<Specialty>(t.getSpecialities()));
        }

        countries = compromisoPaisService.findAll();
        editableProtocoloId = protocolCRUDService.recoverProtocolo().getId();
        protocol = protocolCRUDService.findById(editableProtocoloId);
        chosenCountries = new ArrayList<Integer>(0);
        for(ProtocoloCompromisopais pc : protocol.getProtocoloCompromisopaises()){
            chosenCountries.add(pc.getCompromisopais().getId());
        }
        llamada = "edit";
        return "edit";
    }

    @Action(value="getDrugs", results={
            @Result(name="success",location="/WEB-INF/jsp/Protocols/drugList.jsp")
    })
    public String getDrugs() {

        drogas = drogaService.list(new CriteriaDrug(new Droga(this.drugName, null)));
        return SUCCESS;
    }

    @Action(value="save", results={
            @Result(name="success",location="/protocols.tiles", type="tiles"),
            @Result(name="edit",location="edit", type="redirectAction"),
            @Result(name="input",location="edit", type="redirectAction"),
            @Result(name="select",location="select", type="redirectAction", params = {"editableProtocoloId", "%{editableProtocoloId}"}),
    })
    public String save() {

        Protocolo newProtocol = protocolCRUDService.save(protocol);

        for(Integer c : chosenCountries){
            ProtocoloCompromisopais pcs = new ProtocoloCompromisopais();
            pcs.setProtocolo(newProtocol);
            pcs.setCompromisopais(compromisoPaisService.findById(c));
            pcs.setId(new ProtocoloCompromisopaisId(newProtocol.getId(), c));
            protocoloCompromisopaisService.save(pcs);
        }
        protocol = null;
        if(llamada.equals("edit")){
            llamada = "";
            editableProtocoloId = newProtocol.getId();
            return "select";
        }
        return SUCCESS;
    }



    @Action(value="select", results={
            @Result(name="success",location="/protocols.select.tiles", type="tiles")
    })
    public String select() {
        protocolCRUDService.setProtocolo(editableProtocoloId);

        Map session = ActionContext.getContext().getSession();
       // Compromisopais cp = protocoloCompromisopaisService.getCompromisopaisById(compromisopaisId);

        session.put("protocoloId",editableProtocoloId);
        session.put("compromisopaisid", "");
        session.put("hdargentina",false);
        session.put("hdcolombia",false);
        session.put("hdbrazil",false);
        session.put("hdperu",false);
        session.put("hdchile",false);
        session.put("display","");

        List<Compromisopais> list = protocoloCompromisopaisService.getByProtocoloId(editableProtocoloId);
        for(Compromisopais compromisopais : list){
            if(compromisopais.getCountry().toUpperCase().equals("ARGENTINA")){
                //hdargentina = true;
                ProtocoloCompromisopais pcpArgentina = protocoloCompromisopaisService.getByProtocoloIdCompromisopaisId(editableProtocoloId, compromisopais.getId());
                if(pcpArgentina != null){
                    if(pcpArgentina.getStatus() != null){
                        session.put("statusargentina", "(" + pcpArgentina.getStatus() + ")");
                    }else{
                        session.put("statusargentina", "");
                    }
                }
                session.put("hdargentina",true);
            }
            if(compromisopais.getCountry().toUpperCase().equals("BRASIL") || compromisopais.getCountry().toUpperCase().equals("BRAZIL")){
                //hdbrasil = true;
                ProtocoloCompromisopais pcpBrazil = protocoloCompromisopaisService.getByProtocoloIdCompromisopaisId(editableProtocoloId, compromisopais.getId());
                if(pcpBrazil != null){
                    if(pcpBrazil.getStatus() != null){
                        session.put("statusbrazil", "(" + pcpBrazil.getStatus() + ")");
                    }else{
                        session.put("statusbrazil", "");
                    }
                }
                session.put("hdbrazil",true);
            }
            if(compromisopais.getCountry().toUpperCase().equals("COLOMBIA")) {
              //  hdcolombia = true;
                ProtocoloCompromisopais pcpColombia = protocoloCompromisopaisService.getByProtocoloIdCompromisopaisId(editableProtocoloId, compromisopais.getId());
                if(pcpColombia != null){
                    if(pcpColombia.getStatus() != null){
                        session.put("statuscolombia", "(" + pcpColombia.getStatus() + ")");
                    }else{
                        session.put("statuscolombia", "");
                    }
                }
                session.put("hdcolombia",true);
            }
            if(compromisopais.getCountry().toUpperCase().equals("PERU")){
                //   hdperu = true;
                ProtocoloCompromisopais pcpPeru = protocoloCompromisopaisService.getByProtocoloIdCompromisopaisId(editableProtocoloId, compromisopais.getId());
                if(pcpPeru != null){
                    if(pcpPeru.getStatus() != null){
                        session.put("statusperu", "(" + pcpPeru.getStatus() + ")");
                    }else{
                        session.put("statusperu", "");
                    }
                }
                session.put("hdperu",true);
            }
            if(compromisopais.getCountry().toUpperCase().equals("CHILE")){
                //   hdchile = true;
                ProtocoloCompromisopais pcpChile = protocoloCompromisopaisService.getByProtocoloIdCompromisopaisId(editableProtocoloId, compromisopais.getId());
                if(pcpChile != null){
                    if(pcpChile.getStatus() != null){
                        session.put("statuschile", "(" + pcpChile.getStatus() + ")");
                    }else{
                        session.put("statuschile", "");
                    }
                }
                session.put("hdchile",true);
            }
        }

        return SUCCESS;
    }

    @Action(value="setCountry", results={
            @Result(name="success",location="/protocols.select.tiles", type="tiles")
    })
    public String country() {
        return SUCCESS;
    }

    @Override
    public Object getModel() {
        return protocol;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public Protocolo getProtocol() {
        return protocol;
    }

    public void setProtocol(Protocolo protocol) {
        this.protocol = protocol;
    }

    public String getEditableProtocoloId() {
        return editableProtocoloId;
    }

    public void setEditableProtocoloId(String editableProtocoloId) {
        this.editableProtocoloId = editableProtocoloId;
    }

    public List<Compromisopais> getCountries() {
        return countries;
    }

    public void setCountries(List<Compromisopais> countries) {
        this.countries = countries;
    }

    public List<Integer> getChosenCountries() {
        return chosenCountries;
    }

    public void setChosenCountries(List<Integer> chosenCountries) {
        this.chosenCountries = chosenCountries;
    }

    public List<Droga> getDrogas() {
        return drogas;
    }

    public void setDrogas(List<Droga> drogas) {
        this.drogas = drogas;
    }

    public String getDrugName() {
        return drugName;
    }

    public void setDrugName(String drugName) {
        this.drugName = drugName;
    }

    public LinkedHashMap<TherapeuticArea, ArrayList<Specialty>> getLanguageMap() {
        return languageMap;
    }

    public void setLanguageMap(LinkedHashMap<TherapeuticArea, ArrayList<Specialty>> languageMap) {
        this.languageMap = languageMap;
    }


    public List<Protocolo> getList() {
        return list;
    }

    public void setList(List<Protocolo> list) {
        this.list = list;
    }

    public LinkedHashMap<Protocolo, ArrayList<Compromisopais>> getProtocolosPaises() {
        return protocolosPaises;
    }

    public void setProtocolosPaises(LinkedHashMap<Protocolo, ArrayList<Compromisopais>> protocolosPaises) {
        this.protocolosPaises = protocolosPaises;
    }

    public List<TherapeuticArea> getTherapeuticAreas() {
        return therapeuticAreas;
    }

    public void setTherapeuticAreas(List<TherapeuticArea> therapeuticAreas) {
        this.therapeuticAreas = therapeuticAreas;
    }

    public List<Specialty> getSpecialtyList() {
        return specialtyList;
    }

    public void setSpecialtyList(List<Specialty> specialtyList) {
        this.specialtyList = specialtyList;
    }

    public String getLlamada() {
        return llamada;
    }

    public void setLlamada(String llamada) {
        this.llamada = llamada;
    }
}
